﻿namespace DependencyResolution
open StructureMap
open System.Web.Http.Dependencies;
open Microsoft.Practices.ServiceLocation;
open StructureMap;
//open NewBusiness;
//open NewBusiness.Domain.Uow.Repositories;
//open NewBusiness.Domain.Uow.Data;
//open NewBusiness.Utils;
open System;
open System.Collections.Generic;
open System.Linq;
//open MongoDB.Driver;
[<AbstractClass;Sealed>]
type IoC() =
    static member Initialize(connectionString:string): IContainer  = 
                        ObjectFactory.Initialize(fun x -> x.Scan( fun scan -> //scan.AssemblyContainingType<Business.BusinessDomain.IBusinessContext>(); 
                                                                              scan.AssemblyContainingType<Business.BusinessDomain.IBusinessContext>(); scan.AssemblyContainingType<Data.DataContext>(); scan.TheCallingAssembly(); scan.WithDefaultConventions() |>  ignore;  );
                                                                             //x.For(typedefof<IRepository<_>>).HttpContextScoped().Use(typedefof<Repository<_>>)  |> ignore;
                                                                             x.For(typedefof<Business.Repositories.Repository.IRepository<_>>).HttpContextScoped().Use(typedefof<Business.Repositories.Repository.Repository<_>>).CtorDependency<string>("connectionString").Is(connectionString)  |> ignore;
                                                                             //x.For<DataContext>().HybridHttpOrThreadLocalScoped().Use<DataContext>().Ctor<string>("connectionString").Is(connectionString) |> ignore;
                                                                             x.For<Data.Types.LazyConnection>().HttpContextScoped().Use<Data.Types.LazyConnection>().Ctor<string>("connectionString").Is(connectionString) |> ignore;
                                                                             //x.For<MongoDatabase>().HttpContextScoped().Use(fun () -> MongoClient("mongodb://Neftedollar:gankata@widmore.mongohq.com:10010/tagthisorg").GetServer().GetDatabase("tagthisorg")) |> ignore;
                                                                             x.For<Data.DataContext>().Use<Data.DataContext>().Ctor<string>("connectionString").Is(connectionString) |> ignore;
                                                                             )
                                                                             
                        ObjectFactory.Container

type StructureMapDependencyScope(container: IContainer) = 
              inherit ServiceLocatorImplBase()
              let mutable contaner1:IContainer = container;
              do if container = null then 
                   raise ( System.ArgumentNullException("container"))
              member this.Container with get() = contaner1
              member this.Dispose = (this :> IDependencyScope).Dispose()
              override this.DoGetAllInstances(serviceType :Type) =  this.Container.GetAllInstances(serviceType).Cast<Object>();
              override this.DoGetInstance( serviceType:Type, key:string) = 
                                                                     if String.IsNullOrEmpty(key) then
                                                                        if serviceType.IsAbstract || serviceType.IsInterface then
                                                                           this.Container.TryGetInstance(serviceType)
                                                                        else 
                                                                           this.Container.GetInstance(serviceType)
                                                                     else
                                                                        this.Container.GetInstance(serviceType, key)
              interface IDependencyScope with
                 member this.Dispose() = this.Container.Dispose();
                 member this.GetService(serviceType:Type)  = base.GetService(serviceType)
                 member this.GetServices(serviceType:Type) = this.Container.GetAllInstances(serviceType).Cast<Object>()
                     
              
type StructureMapDependencyResolver(contaner:IContainer) =
   inherit StructureMapDependencyScope(contaner)
   interface IDependencyResolver with
      member  this.BeginScope() = 
         (new StructureMapDependencyResolver(this.Container.GetNestedContainer())) :> IDependencyScope

//type StructureMapDependencyResolver = 
//     inherit IDependencyResolver
     